/*     */ package com.zimbra.cs.service.admin;
/*     */ 
/*     */ import com.google.common.base.Splitter;
/*     */ import com.google.common.collect.Lists;
/*     */ import com.google.common.collect.TreeMultimap;
/*     */ import com.zimbra.common.account.Key.DomainBy;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.AdminConstants;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.cs.account.AccountServiceException;
/*     */ import com.zimbra.cs.account.Domain;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Provisioning.DirectoryEntryVisitor;
/*     */ import com.zimbra.cs.account.accesscontrol.AdminRight;
/*     */ import com.zimbra.cs.account.accesscontrol.Rights.Admin;
/*     */ import com.zimbra.cs.session.AdminSession;
/*     */ import com.zimbra.cs.session.Session.Type;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import java.util.Arrays;
/*     */ import java.util.Collection;
/*     */ import java.util.HashSet;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Map.Entry;
/*     */ import java.util.Set;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class SearchAutoProvDirectory
/*     */   extends AdminDocumentHandler
/*     */ {
/*     */   public Element handle(Element request, Map<String, Object> context)
/*     */     throws ServiceException
/*     */   {
/*  47 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/*  48 */     Provisioning prov = Provisioning.getInstance();
/*     */     
/*  50 */     String query = request.getAttribute("query", null);
/*  51 */     String name = request.getAttribute("name", null);
/*     */     
/*  53 */     if ((query != null) && (name != null)) {
/*  54 */       throw ServiceException.INVALID_REQUEST("only one of filter or name can be provided", null);
/*     */     }
/*     */     
/*  57 */     int maxResults = (int)request.getAttributeLong("maxResults", SearchDirectory.MAX_SEARCH_RESULTS);
/*     */     
/*  59 */     int limit = (int)request.getAttributeLong("limit", 2147483647L);
/*  60 */     if (limit == 0) {
/*  61 */       limit = Integer.MAX_VALUE;
/*     */     }
/*  63 */     int offset = (int)request.getAttributeLong("offset", 0L);
/*  64 */     boolean refresh = request.getAttributeBool("refresh", false);
/*     */     
/*  66 */     String keyAttr = request.getAttribute("keyAttr");
/*     */     
/*  68 */     String attrsStr = request.getAttribute("attrs", null);
/*  69 */     String[] returnAttrs = null;
/*  70 */     if (attrsStr != null) {
/*  71 */       Set<String> attrs = new HashSet();
/*  72 */       for (String attr : Splitter.on(',').trimResults().split(attrsStr)) {
/*  73 */         attrs.add(attr);
/*     */       }
/*  75 */       if (!attrs.contains(keyAttr)) {
/*  76 */         attrs.add(keyAttr);
/*     */       }
/*  78 */       returnAttrs = (String[])attrs.toArray(new String[attrs.size()]);
/*     */     }
/*     */     
/*  81 */     Element eDomain = request.getElement("domain");
/*  82 */     Key.DomainBy domainBy = Key.DomainBy.fromString(eDomain.getAttribute("by"));
/*  83 */     String domainValue = eDomain.getText();
/*  84 */     Domain domain = prov.get(domainBy, domainValue);
/*  85 */     if (domain == null) {
/*  86 */       throw AccountServiceException.NO_SUCH_DOMAIN(domainValue);
/*     */     }
/*     */     
/*  89 */     checkRight(zsc, context, domain, Rights.Admin.R_autoProvisionAccount);
/*     */     
/*  91 */     AdminSession session = (AdminSession)getSession(zsc, Session.Type.ADMIN);
/*     */     
/*  93 */     List<Entry> entryList = null;
/*  94 */     if (session != null) {
/*  95 */       SearchAutoProvDirectory.Cache.Params params = new SearchAutoProvDirectory.Cache.Params(domain, query, name, keyAttr, returnAttrs, maxResults, null);
/*     */       
/*     */ 
/*  98 */       if (!refresh) {
/*  99 */         entryList = Cache.getFromCache(session, params);
/*     */       }
/* 101 */       if (entryList == null) {
/* 102 */         entryList = search(domain, query, name, keyAttr, returnAttrs, maxResults);
/* 103 */         Cache.putInCache(session, params, entryList);
/*     */       }
/*     */     }
/*     */     else {
/* 107 */       entryList = search(domain, query, name, keyAttr, returnAttrs, maxResults);
/*     */     }
/*     */     
/* 110 */     Element response = zsc.createElement(AdminConstants.SEARCH_AUTO_PROV_DIRECTORY_RESPONSE);
/* 111 */     encodeEntries(response, entryList, keyAttr, offset, limit);
/* 112 */     return response;
/*     */   }
/*     */   
/*     */   private static class Cache
/*     */   {
/*     */     private static final String SEARCH_AUTO_PROV_DIRECTORY_CACHE_KEY = "SearchAutoProvDirectory";
/*     */     
/*     */     private static class Params {
/*     */       Domain domain;
/*     */       String query;
/*     */       String name;
/*     */       String keyAttr;
/*     */       String[] returnAttrs;
/*     */       int maxResults;
/*     */       
/*     */       private Params(Domain domain, String query, String name, String keyAttr, String[] returnAttrs, int maxResults) {
/* 128 */         this.domain = domain;
/* 129 */         this.query = query;
/* 130 */         this.name = name;
/* 131 */         this.keyAttr = keyAttr;
/* 132 */         this.returnAttrs = returnAttrs;
/* 133 */         this.maxResults = maxResults;
/*     */       }
/*     */       
/*     */       public boolean equals(Object other)
/*     */       {
/* 138 */         if ((other instanceof Params)) {
/* 139 */           Params otherParams = (Params)other;
/*     */           
/* 141 */           if (!this.domain.getId().equals(otherParams.domain.getId())) {
/* 142 */             return false;
/*     */           }
/*     */           
/* 145 */           if (!equals(this.query, otherParams.query)) {
/* 146 */             return false;
/*     */           }
/*     */           
/* 149 */           if (!equals(this.name, otherParams.name)) {
/* 150 */             return false;
/*     */           }
/*     */           
/* 153 */           if (!equals(this.keyAttr, otherParams.keyAttr)) {
/* 154 */             return false;
/*     */           }
/*     */           
/* 157 */           if (this.maxResults != otherParams.maxResults) {
/* 158 */             return false;
/*     */           }
/*     */           
/* 161 */           if (!equals(this.returnAttrs, otherParams.returnAttrs)) {
/* 162 */             return false;
/*     */           }
/*     */           
/* 165 */           return true;
/*     */         }
/* 167 */         return false;
/*     */       }
/*     */       
/*     */       private boolean equals(String s1, String s2)
/*     */       {
/* 172 */         if (s1 == null) {
/* 173 */           return s2 == null;
/*     */         }
/* 175 */         return s1.equals(s2);
/*     */       }
/*     */       
/*     */       private boolean equals(String[] s1, String[] s2)
/*     */       {
/* 180 */         if (s1 == null) {
/* 181 */           return s2 == null;
/*     */         }
/* 183 */         if (s2 == null) {
/* 184 */           return false;
/*     */         }
/* 186 */         if (s1.length != s2.length) {
/* 187 */           return false;
/*     */         }
/* 189 */         Set<String> set1 = new HashSet(Arrays.asList(s1));
/* 190 */         Set<String> set2 = new HashSet(Arrays.asList(s2));
/* 191 */         return set1.equals(set2);
/*     */       }
/*     */     }
/*     */     
/*     */     private static class CachedResult
/*     */     {
/*     */       private SearchAutoProvDirectory.Cache.Params params;
/*     */       private List<SearchAutoProvDirectory.Entry> result;
/*     */       
/*     */       private CachedResult(SearchAutoProvDirectory.Cache.Params params, List<SearchAutoProvDirectory.Entry> result)
/*     */       {
/* 202 */         this.params = params;
/* 203 */         this.result = result;
/*     */       }
/*     */     }
/*     */     
/*     */     private static List<SearchAutoProvDirectory.Entry> getFromCache(AdminSession session, Params params) {
/* 208 */       Object cached = session.getData("SearchAutoProvDirectory");
/* 209 */       if (cached == null) {
/* 210 */         return null;
/*     */       }
/*     */       
/* 213 */       CachedResult cachedResult = (CachedResult)cached;
/* 214 */       if (cachedResult.params.equals(params)) {
/* 215 */         return cachedResult.result;
/*     */       }
/*     */       
/* 218 */       return null;
/*     */     }
/*     */     
/*     */     private static void putInCache(AdminSession session, Params params, List<SearchAutoProvDirectory.Entry> result) {
/* 222 */       CachedResult cachedResult = new CachedResult(params, result, null);
/* 223 */       session.setData("SearchAutoProvDirectory", cachedResult);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   private void encodeEntries(Element response, List<Entry> entryList, String keyAttr, int offset, int limit)
/*     */   {
/* 230 */     int totalEntries = entryList.size();
/*     */     
/* 232 */     int limitMax = offset + limit;
/* 233 */     Element eEntry; for (int i = offset; (i < limitMax) && (i < totalEntries); i++) {
/* 234 */       Entry entry = (Entry)entryList.get(i);
/*     */       
/* 236 */       eEntry = response.addElement("entry");
/* 237 */       eEntry.addAttribute("dn", entry.dn);
/*     */       
/* 239 */       Object keyValue = entry.attrs.get(keyAttr);
/* 240 */       if (keyValue != null) {
/* 241 */         encodeKey(eEntry, keyValue);
/*     */       }
/*     */       
/* 244 */       for (Map.Entry<String, Object> attr : entry.attrs.entrySet()) {
/* 245 */         String attrName = (String)attr.getKey();
/* 246 */         if (!attrName.equals(keyAttr)) {
/* 247 */           encodeAttr(eEntry, attrName, attr.getValue());
/*     */         }
/*     */       }
/*     */     }
/*     */     
/* 252 */     response.addAttribute("more", i < totalEntries);
/* 253 */     response.addAttribute("searchTotal", totalEntries);
/*     */   }
/*     */   
/*     */   private void encodeKey(Element parent, Object value) {
/* 257 */     if ((value instanceof String))
/* 258 */       parent.addElement("key").setText((String)value);
/* 259 */     if ((value instanceof String[])) {
/* 260 */       for (String v : (String[])value) {
/* 261 */         parent.addElement("key").setText(v);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   private void encodeAttr(Element parent, String attrName, Object value) {
/* 267 */     if ((value instanceof String)) {
/* 268 */       parent.addElement("a").addAttribute("n", attrName).setText((String)value);
/*     */     } else {
/* 270 */       for (String v : (String[])value) {
/* 271 */         parent.addElement("a").addAttribute("n", attrName).setText(v);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   private static class Entry implements Comparable<Entry> {
/*     */     private String dn;
/*     */     private Map<String, Object> attrs;
/*     */     
/*     */     private Entry(String dn, Map<String, Object> attrs) {
/* 281 */       this.dn = dn;
/* 282 */       this.attrs = attrs;
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */     public int compareTo(Entry other)
/*     */     {
/* 293 */       return 1;
/*     */     }
/*     */   }
/*     */   
/*     */   private static class Result
/*     */     implements Provisioning.DirectoryEntryVisitor
/*     */   {
/*     */     private String keyAttr;
/* 301 */     private TreeMultimap<String, SearchAutoProvDirectory.Entry> entries = TreeMultimap.create();
/*     */     
/*     */     private Result(String keyAttr) {
/* 304 */       this.keyAttr = keyAttr;
/*     */     }
/*     */     
/*     */     public void visit(String dn, Map<String, Object> attrs)
/*     */     {
/* 309 */       String key = null;
/* 310 */       Object value = attrs.get(this.keyAttr);
/* 311 */       if ((value instanceof String)) {
/* 312 */         key = (String)value;
/* 313 */       } else if ((value instanceof String[])) {
/* 314 */         String[] values = (String[])value;
/* 315 */         if (values.length > 1) {
/* 316 */           key = values[0];
/*     */         }
/*     */       }
/*     */       
/* 320 */       if (key == null) {
/* 321 */         key = "";
/*     */       }
/*     */       
/* 324 */       this.entries.put(key, new SearchAutoProvDirectory.Entry(dn, attrs, null));
/*     */     }
/*     */     
/*     */     private Collection<SearchAutoProvDirectory.Entry> getEntries() {
/* 328 */       return this.entries.values();
/*     */     }
/*     */     
/*     */     private int size() {
/* 332 */       return this.entries.size();
/*     */     }
/*     */   }
/*     */   
/*     */   private List<Entry> search(Domain domain, String query, String name, String keyAttr, String[] returnAttrs, int maxResults)
/*     */     throws ServiceException
/*     */   {
/* 339 */     Result result = new Result(keyAttr, null);
/*     */     
/* 341 */     Provisioning.getInstance().searchAutoProvDirectory(domain, query, name, returnAttrs, maxResults, result);
/*     */     
/*     */ 
/* 344 */     List<Entry> entryList = Lists.newArrayListWithExpectedSize(result.size());
/* 345 */     entryList.addAll(result.getEntries());
/* 346 */     return entryList;
/*     */   }
/*     */   
/*     */   public void docRights(List<AdminRight> relatedRights, List<String> notes)
/*     */   {
/* 351 */     relatedRights.add(Rights.Admin.R_autoProvisionAccount);
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/admin/SearchAutoProvDirectory.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */